﻿using Item.Buff;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Battle;
using LitJson;

namespace ItemComponent
{
    public class Gun : MyItemComponentMono
    {
        protected const string Key_GunData = "GunData";

#if UNITY_EDITOR
        [ReadOnly,SerializeField]
        private ST_GunData debugGunData;
#endif

        public ST_GunData GunData { get; protected set; }
        public ST_GunData CurGunData { get; protected set; }

        protected double fMarkTime;
        protected int nCurClipNum;
        protected bool bReload;

        
        public override void InitComponent(JsonData data, Item.ItemBase item)
        {
            if (data == null | data[Key_GunData] == null) return;

            ST_GunData tmp = JsonMapper.ToObject<ST_GunData>(data[Key_GunData].ToJson());

            GunData = tmp;
            CurGunData = tmp;

#if UNITY_EDITOR
            debugGunData = tmp;
#endif

            fMarkTime = 0;
            nCurClipNum = tmp.nMaxClipCount;
            bReload = false;
        }

        protected virtual void Start()
        {
            enabled = false;
        }

        protected virtual void Update()
        {
            fMarkTime += Time.deltaTime;

            if (bReload)
            {
                if (fMarkTime >= CurGunData.dClipReLoadTime)
                {
                    //换弹时间结束
                    OnReloadOver();
                }
            }

            if (!bReload)
            {
                var target = Battle.EnemyMgr.Ins.GetTarget(transform.position);

                if (fMarkTime > CurGunData.dFireInterval)
                {
                    if (target != null)
                    {
                        //有目标
                        FireAsync(target);
                        fMarkTime -= CurGunData.dFireInterval;

                        if (--nCurClipNum <= 0)
                        {
                            //弹夹打空
                            Reload();
                        }
                    }
                    else
                    {
                        if (nCurClipNum != CurGunData.nMaxClipCount)
                        {
                            //没目标自动换弹
                            Reload();
                        }
                        else
                        {
                            //不换弹锁定时间
                            fMarkTime = CurGunData.dFireInterval;
                        }
                    }
                }
            }
        }

        protected virtual void Reload()
        {
            fMarkTime = 0;
            bReload = true;
        }
        protected virtual void OnReloadOver()
        {
            fMarkTime -= CurGunData.dClipReLoadTime;
            nCurClipNum = CurGunData.nMaxClipCount;
            bReload = false;
        }

        protected async virtual void FireAsync(ICanHitObj target)
        {
            if (target == null) return;
            await BulletFactory.CreateNormalBulletAsync(GetBulletData(target));

            // BulletFactory.CreateNormalBullet(transform.position, target.transform.position, CurGunData.nBulletDmg, (float)CurGunData.fBulletSpeed);
        }

        protected virtual ST_BulletData GetBulletData(ICanHitObj target) {
            return new ST_BulletData()
            {
                vBornPos = transform.position,
                vTargetPos = target?.Pos??default,
                nDmg = CurGunData.nBulletDmg,
                fSpeed = (float)CurGunData.dBulletSpeed,

                nCatapultCount = CurGunData.specialAtkData.nCatapultCount,
                nPenetrateCount=CurGunData.specialAtkData.nPenetrateCount,
                nRepelNum=CurGunData.specialAtkData.nRepelNum,
                fLifeTime=(float)CurGunData.dLifeTime,
            };
        }

        public override void OnBuffChange(STBuffEffectData buffEffectData)
        {
            var tmpData = GunData;
            float bulletNumOneSecond = 1f / (float)tmpData.dFireInterval;
            float readLoadOneSecond = 1f / (float)tmpData.dClipReLoadTime;

            tmpData.nBulletDmg = Mathf.RoundToInt(tmpData.nBulletDmg * buffEffectData.fPower * buffEffectData.fGunGroup);
            tmpData.dFireInterval = 1f / (bulletNumOneSecond * buffEffectData.fSpeed * buffEffectData.fGunGroup);
            tmpData.dBulletSpeed *= buffEffectData.fSpeed;
            tmpData.dClipReLoadTime = 1f / (readLoadOneSecond * buffEffectData.fSpeed);

            var tmpSpecialData = GunData.specialAtkData;

            tmpSpecialData.nCatapultCount += buffEffectData.nCatapultNum;
            tmpSpecialData.nPenetrateCount += buffEffectData.nPenetrateNum;

            //自身没有击退，但是加了击退辅助，击退值就是攻击力
            if (tmpSpecialData.nRepelNum == 0 && buffEffectData.fRepel > 1)
                tmpSpecialData.nRepelNum = tmpData.nBulletDmg;

            tmpSpecialData.nRepelNum = Mathf.RoundToInt(tmpSpecialData.nRepelNum * buffEffectData.fRepel);

            tmpData.specialAtkData = tmpSpecialData;
            CurGunData = tmpData;

#if UNITY_EDITOR
            debugGunData = tmpData;
#endif
        }

        public override string GetDes()
        {
            SB.Clear();
            SB.Append("攻击力:");
            SB.Append(CurGunData.nBulletDmg);
            SB.Append(" 攻击间隔:");
            SB.Append(CurGunData.dFireInterval.ToString("0.0"));
            
            SB.Append("\n弹夹:(");
            SB.Append(nCurClipNum);
            SB.Append('/');
            SB.Append(CurGunData.nMaxClipCount);
            SB.Append(')');

            SB.Append(" 换弹时间:");
            SB.Append(CurGunData.dClipReLoadTime.ToString("0.0"));

            return SB.ToString() ;
        }

#if UNITY_EDITOR
        public static STMyComponetData GetMyComponetData(ST_GunData gunData)
        {
            JsonData json = new JsonData();
            json[Key_GunData] = JsonMapper.ToObject(JsonMapper.ToJson(gunData));

            return new STMyComponetData()
            {
                strType=typeof(Gun).FullName,
                data=json,
            };
        }
#endif
    }
}